home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / program / ixemlsrc.lha / ixemul / library / kern_time.c < prev    next >
C/C++ Source or Header  |  1995-12-23  |  6KB  |  209 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  kern_time.c,v 1.1.1.1 1994/04/04 04:30:41 amiga Exp
  20.  *
  21.  *  kern_time.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:41  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.1  1992/05/14  19:55:40  mwild
  26.  *  Initial revision
  27.  *
  28.  *
  29.  *  Since the code originated from Berkeley, the following copyright
  30.  *  header applies as well. The code has been changed, it's not the
  31.  *  original Berkeley code!
  32.  */
  33.  
  34. /*
  35.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  36.  * All rights reserved.
  37.  *
  38.  * Redistribution is only permitted until one year after the first shipment
  39.  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
  40.  * binary forms are permitted provided that: (1) source distributions retain
  41.  * this entire copyright notice and comment, and (2) distributions including
  42.  * binaries display the following acknowledgement:  This product includes
  43.  * software developed by the University of California, Berkeley and its
  44.  * contributors'' in the documentation or other materials provided with the
  45.  * distribution and in all advertising materials mentioning features or use
  46.  * of this software.  Neither the name of the University nor the names of
  47.  * its contributors may be used to endorse or promote products derived from
  48.  * this software without specific prior written permission.
  49.  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  50.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  51.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  52.  *
  53.  *    @(#)kern_time.c    7.13 (Berkeley) 6/28/90
  54.  */
  55.  
  56. #define KERNEL
  57. #include "ixemul.h"
  58. #include "kprintf.h"
  59.  
  60. #include <sys/time.h>
  61.  
  62. #define err_return(code) \
  63. {                    \
  64.   errno = code;                \
  65.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno)); \
  66.   return errno == 0 ? 0 : -1;        \
  67. }
  68.  
  69. int  itimerfix(struct timeval *tv);
  70. void timevalfix(struct timeval *t1);
  71. void timevaladd(struct timeval *t1, const struct timeval *t2);
  72. void timevalsub(struct timeval *t1, const struct timeval *t2);
  73.  
  74. int
  75. getitimer(u_int    which, struct itimerval *itv)
  76. {
  77.   if (which > ITIMER_PROF || !itv)
  78.     err_return (EINVAL);
  79.  
  80.   Disable ();
  81.   *itv = u.u_timer[which];
  82.   Enable();
  83.  
  84.   err_return (0);
  85. }
  86.  
  87. int
  88. setitimer(u_int    which, const struct itimerval *itv, struct itimerval *oitv)
  89. {
  90.     if (which > ITIMER_PROF)
  91.         err_return (EINVAL);
  92.  
  93.     if (oitv && getitimer(which, oitv))
  94.         return -1;
  95.     if (itv == 0)
  96.         err_return (0);
  97.  
  98.     if (itimerfix((struct timeval *)&itv->it_value) || 
  99.         itimerfix((struct timeval *)&itv->it_interval))
  100.         err_return (EINVAL);
  101.  
  102.     Disable ();
  103.     u.u_timer[which] = *itv;
  104.     Enable ();
  105.  
  106.     err_return (0);
  107. }
  108.  
  109. /*
  110.  * Check that a proposed value to load into the .it_value or
  111.  * .it_interval part of an interval timer is acceptable, and
  112.  * fix it to have at least minimal value (i.e. if it is less
  113.  * than the resolution of the clock, round it up.)
  114.  */
  115. int itimerfix(struct timeval *tv)
  116. {
  117.     if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
  118.         tv->tv_usec < 0 || tv->tv_usec >= 1000000)
  119.         err_return (EINVAL);
  120.     if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < ITIMER_RESOLUTION)
  121.         tv->tv_usec = ITIMER_RESOLUTION;
  122.     err_return (0);
  123. }
  124.  
  125. /*
  126.  * Decrement an interval timer by a specified number
  127.  * of microseconds, which must be less than a second,
  128.  * i.e. < 1000000.  If the timer expires, then reload
  129.  * it.  In this case, carry over (usec - old value) to
  130.  * reducint the value reloaded into the timer so that
  131.  * the timer does not drift.  This routine assumes
  132.  * that it is called in a context where the timers
  133.  * on which it is operating cannot change in value.
  134.  */
  135.  
  136. /* on 0 return, send a signal to process */
  137.  
  138. int
  139. itimerdecr (struct itimerval *itp, int usec)    /* CALLED FROM INTERRUPT !! */
  140. {
  141.   if (itp->it_value.tv_usec < usec) 
  142.     {
  143.       if (itp->it_value.tv_sec == 0) 
  144.     {
  145.       /* expired, and already in next interval */
  146.       usec -= itp->it_value.tv_usec;
  147.       goto expire;
  148.     }
  149.  
  150.       itp->it_value.tv_usec += 1000000;
  151.       itp->it_value.tv_sec--;
  152.     }
  153.  
  154.   itp->it_value.tv_usec -= usec;
  155.   usec = 0;
  156.   if (timerisset(&itp->it_value))
  157.     return (1);
  158.  
  159.   /* expired, exactly at end of interval */
  160. expire:
  161.   if (timerisset(&itp->it_interval)) 
  162.     {
  163.       itp->it_value = itp->it_interval;
  164.       itp->it_value.tv_usec -= usec;
  165.       if (itp->it_value.tv_usec < 0) 
  166.         {
  167.       itp->it_value.tv_usec += 1000000;
  168.       itp->it_value.tv_sec--;
  169.     }
  170.     } 
  171.   else
  172.     itp->it_value.tv_usec = 0;        /* sec is already 0 */
  173.  
  174.   return (0);
  175. }
  176.  
  177. /*
  178.  * Add and subtract routines for timevals.
  179.  * N.B.: subtract routine doesn't deal with
  180.  * results which are before the beginning,
  181.  * it just gets very confused in this case.
  182.  * Caveat emptor.
  183.  */
  184. void timevaladd(struct timeval *t1, const struct timeval *t2)
  185. {
  186.     t1->tv_sec += t2->tv_sec;
  187.     t1->tv_usec += t2->tv_usec;
  188.     timevalfix(t1);
  189. }
  190.  
  191. void timevalsub(struct timeval *t1, const struct timeval *t2)
  192. {
  193.     t1->tv_sec -= t2->tv_sec;
  194.     t1->tv_usec -= t2->tv_usec;
  195.     timevalfix(t1);
  196. }
  197.  
  198. void timevalfix(struct timeval *t1)
  199. {
  200.     if (t1->tv_usec < 0) {
  201.         t1->tv_sec--;
  202.         t1->tv_usec += 1000000;
  203.     }
  204.     if (t1->tv_usec >= 1000000) {
  205.         t1->tv_sec++;
  206.         t1->tv_usec -= 1000000;
  207.     }
  208. }
  209.